001 /* 002 * Copyright 2005 Stephen J. McConnell. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 013 * implied. 014 * 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package net.dpml.lang; 020 021 import java.util.Arrays; 022 023 /** 024 * A object resolvable from primitive arguments. 025 * 026 * @author <a href="http://www.dpml.net">Digital Product Meta Library</a> 027 * @version 1.0.2 028 */ 029 public class ValueDirective extends AbstractDirective 030 { 031 private final String m_method; 032 private final String m_target; 033 private final String m_value; 034 private final ValueDirective[] m_args; 035 private final boolean m_compound; 036 037 /** 038 * Create a new value descriptor using the default java.lang.String class as the base type. 039 * @param value the construct value 040 */ 041 public ValueDirective( String value ) 042 { 043 this( null, null, value ); 044 } 045 046 /** 047 * Create a new construct using a supplied target definition. The target argument 048 * may be either a classname or a symbolic object reference in the form ${[key]}. 049 * 050 * @param target a classname or symbolic object reference 051 * @param value the construct value 052 */ 053 public ValueDirective( String target, String value ) 054 { 055 this( target, null, value ); 056 } 057 058 /** 059 * Create a new construct using a supplied target defintion. The target argument 060 * may be either a classname or a symbolic reference in the form ${[key]}. If the 061 * argument is symbolic it is resolved relative to a context map supplied by the 062 * application resolving construct values. If the construct value is symbolic 063 * the implementation will attempt to expand the reference relative to a context 064 * map (if supplied) otherwise the implementation will attempt to expand the value 065 * using system properties. 066 * 067 * @param target a classname or symbolic reference 068 * @param method the method to invoke on the target 069 * @param value the construct value 070 */ 071 public ValueDirective( String target, String method, String value ) 072 { 073 super(); 074 m_target = target; 075 m_method = method; 076 m_value = value; 077 m_args = new ValueDirective[0]; 078 m_compound = false; 079 } 080 081 /** 082 * Create a new construct using a supplied target defintion. The target argument 083 * may be either a classname or a symbolic reference in the form ${[key]}. If the 084 * argument is symbolic it is resolved relative to a context map supplied by the 085 * application resolving construct values. Instance values resolved from the 086 * supplied Value[] will be used as constructor arguments when resolving the target. 087 * 088 * @param target the construct classname 089 * @param args an array of unresolved parameter values 090 */ 091 public ValueDirective( String target, ValueDirective[] args ) 092 { 093 this( target, null, args ); 094 } 095 096 /** 097 * Create a new construct using a supplied target defintion. The target argument 098 * may be either a classname or a symbolic reference in the form ${[key]}. If the 099 * argument is symbolic it is resolved relative to a context map supplied by the 100 * application resolving construct values. Instance values resolved from the 101 * supplied Value[] will be used as method arguments when resolving the target. 102 * 103 * @param target the construct classname 104 * @param method the method to invoke on the target 105 * @param args an array of unresolved parameter values 106 */ 107 public ValueDirective( String target, String method, ValueDirective[] args ) 108 { 109 super(); 110 if( null == args ) 111 { 112 m_args = new ValueDirective[0]; 113 } 114 else 115 { 116 m_args = args; 117 } 118 m_value = null; 119 m_target = target; 120 m_method = method; 121 m_compound = true; 122 } 123 124 /** 125 * Return TRUE if this construct is a compund construct else FALSE. 126 * @return TRUE if this ia a compound construct 127 */ 128 public boolean isCompound() 129 { 130 return m_compound; 131 } 132 133 /** 134 * Return the method name to be applied to the target object. 135 * @return the method name 136 */ 137 public String getMethodName() 138 { 139 return m_method; 140 } 141 142 /** 143 * Return the set of nested values within this value. 144 * @return the nested values array 145 */ 146 public ValueDirective[] getValueDirectives() 147 { 148 return m_args; 149 } 150 151 /** 152 * Return the base value of the resolved value. 153 * @return the base value 154 */ 155 public String getBaseValue() 156 { 157 return m_value; 158 } 159 160 /** 161 * Return the classname of the resolved value. 162 * @return the classname 163 */ 164 public String getTargetExpression() 165 { 166 return m_target; 167 } 168 169 /** 170 * Return a string representation of the construct. 171 * @return the string value 172 */ 173 public String toString() 174 { 175 if( !m_compound ) 176 { 177 return "value " 178 + " target: " + m_target 179 + " method: " + m_method 180 + " value: " + m_value; 181 } 182 else 183 { 184 return "value " 185 + " target: " + m_target 186 + " method: " + m_method 187 + " values: " + m_args.length; 188 } 189 } 190 191 /** 192 * Compare this instance with a supplied object for equality. 193 * @param other the other object 194 * @return true if the supplied instance is equal to this instance 195 */ 196 public boolean equals( Object other ) 197 { 198 if( super.equals( other ) && ( other instanceof ValueDirective ) ) 199 { 200 ValueDirective construct = (ValueDirective) other; 201 if( !equals( m_target, construct.m_target ) ) 202 { 203 return false; 204 } 205 if( m_compound != construct.m_compound ) 206 { 207 return false; 208 } 209 if( !equals( m_method, construct.m_method ) ) 210 { 211 return false; 212 } 213 if( m_compound ) 214 { 215 return Arrays.equals( m_args, construct.m_args ); 216 } 217 else 218 { 219 return equals( m_value, construct.m_value ); 220 } 221 } 222 else 223 { 224 return false; 225 } 226 } 227 228 /** 229 * Compute the instance hashcode value. 230 * @return the hashcode 231 */ 232 public int hashCode() 233 { 234 int hash = 0; 235 hash ^= hashValue( m_target ); 236 hash ^= hashValue( m_method ); 237 hash ^= hashArray( m_args ); 238 hash ^= hashValue( m_value ); 239 return hash; 240 } 241 }